import datetime
import json
import logging

from instructions.enum_types import InstructionType, ActionType
from instructions.instruction import Instruction
from instructions.static_instruction import StaticInstruction
from models import Customers, Order, Kumquats
from prompt_template import prompt_tpl
from tools import action_logger, over_deadline, check_contain, clean_ai_json
from wechat.reply import Reply, ReplyType
from config import config, kqConfig, aiConfig, envConfig

logger = logging.getLogger(__name__)


class ImportMSGInstruction(Instruction):
    """
    This class of Instruction is used to handle the file loading. No AI used.
    The format is checked, so no worry about it.
    In this case, query argument is supposed to be the reference information and the user's instruction words.
    """

    def __init__(self, chatDBHandler=None, query=None):
        super().__init__(chatDBHandler, query)
        self.insType = InstructionType.IMPORT_BY_WORDS
        self.prompt = aiConfig.CHARACTER_DESC
        self.msgType = "金桔信息" if "金桔" in self.query else "订单信息"

    @action_logger(ActionType.HANDLER_QUERY)
    async def handle_query(self) -> Reply:
        """
        用AI判断信息种类，金桔信息还是订单信息 --> 我错了，AI分不出来
        解析AI给的结果
        金桔信息必须私聊
        订单信息需要检查是否过了截止时间
        :return:
        """
        try:
            self.chatDBHandler.add_actions(ActionType.CHECK_MSG_TYPE)
            if self.msgType == "金桔信息":
                if self.chatDBHandler.msg.is_group:
                    return Reply(ReplyType.TEXT, "金桔信息是敏感信息,只能私聊我噢[呲牙]，请私聊我，谢谢！")
                self.prompt += prompt_tpl.PARSE_KUMQUAT_PROMPT
                # self.prompt = self.prompt.replace("QUERY", self.query)
            else:
                self.prompt += prompt_tpl.PARSE_ORDER_PROMPT
                # self.prompt = self.prompt.replace("QUERY", self.query).replace("NICKNAME", self.chatDBHandler.nn)
                self.chatDBHandler.add_actions(ActionType.CHECK_DEADLINE)
                delta = over_deadline()
                if delta.days < 0 and config.PACKAGE_DEADLINE_ON:
                    self.chatDBHandler.add_actions(ActionType.OVER_DEADLINE)
                    logger.warning("[deadline check] Order loaded is over time. No need to handle!")
                    return Reply(ReplyType.TEXT, StaticInstruction.generate_over_deadline_msg(delta, True))

            order_json = await self.query_ollama()
            if not order_json:
                order_json = await self.query_other()
                if not order_json:
                    return Reply(ReplyType.TEXT, "额..额..我的大脑被僵尸吃掉了,要过一会才能长出来[骷髅]")
            word_info = json.loads(clean_ai_json(order_json))
            if word_info.get("result"):
                return Reply(ReplyType.TEXT,
                             word_info.get("reason", "解析失败，请检查你的输入是否正确，或者联系我爹@{envConfig.DAD_NN}"))
            logger.info(f"[instruction] Get parsed order information from AI.{word_info}")

            if "加金桔" in self.query or word_info.get("msg_type") == "金桔信息":
                res = await self.insert_one_order(word_info)
            else:
                if check_contain(self.query, envConfig.FORCE_IMPORT_KEYS):
                    res = await self.insert_one_order(word_info, force_flag=True)
                else:
                    res = await self.insert_one_order(word_info)
            return Reply(ReplyType.TEXT, word_info.get("success_info", res))
        except ValueError as e:
            self.chatDBHandler.note = str(e)
            self.chatDBHandler.add_actions(ActionType.JSON_ERROR)
            logger.exception(e)
            return Reply(ReplyType.ERROR, f"解析失败，请检查你的输入是否正确，或者联系我爹@{envConfig.DAD_NN}")
        except Exception as e:
            self.chatDBHandler.note = str(e)
            self.chatDBHandler.add_actions(ActionType.UNKNOWN_ERROR)
            logger.exception(e)
            return Reply(ReplyType.ERROR, f"出问题了..这个是错误{e}, 快联系我爹@{envConfig.DAD_NN}")

    @action_logger(ActionType.INSER_WORD_QUERY)
    async def insert_one_order(self, word_info: dict, force_flag=False) -> str:
        """
        1. 对AI返回的JSON数据进行检查，经过多次测试，它大概率无法识别quantity缺少的问题，不过好在会在返回信息里写个null。
        2. 检查金桔规格是否存在于该用户的数据库中
        3. 检查客户是否已经存在
        4. 插入数据
        :return:
        """
        success_info = word_info.pop("success_info")
        if self.msgType == "金桔信息":
            if not word_info.get("name") or not word_info.get("format") or not word_info.get("price"):
                word_info["original_price"] = 0 if word_info.get("original_price") else word_info["original_price"]
                return "金桔信息不全，名称，规格，售价都要写清楚噢~"
            else:
                await Kumquats.filter(name=word_info["name"], format=word_info["format"]).update(note='OLD')
                new_record = await Kumquats.create(name=word_info["name"], format=word_info["format"],
                                                   original_price=word_info["original_price"],
                                                   price=word_info["price"], users_id=self.chatDBHandler.user_id,
                                                   note='CURRENT')

        else:
            if not word_info.get("customers__name") or not word_info.get("customers__phone") \
                    or not word_info.get("customers__address") or not \
                    word_info.get("kumquats__name") or not word_info.get("kumquats__format") \
                    or not word_info.get("quantity") or not \
                    word_info.get("on_sold"):
                logger.warning("[process] 果然缺了信息， AI 不值得信任！")
                return "似乎信息不全，是不是没写箱数？[疑问]"
            kumquat = await self.chatDBHandler.check_user_has_kumquat(word_info["kumquats__name"],
                                                                      word_info["kumquats__format"], force_flag)
            if not kumquat:
                return f"⚠️你还没输入这个规格的金桔：{word_info['kumquats__name']} {word_info['kumquats__format']}\n" \
                       f"⚠️请!私聊!我加入这款金桔的信息，才能录入这个订单噢~, 如果需要用果场默认的金桔信息，请@我，加入【直接加单】的关键字，以及【订单信息】。\n"

            customer = await Customers.filter(name=word_info["customers__name"],
                                              address=word_info["customers__address"],
                                              phone=word_info["customers__phone"]).first()

            if not customer:
                customer = await Customers.create(name=word_info["customers__name"],
                                                  address=word_info["customers__address"],
                                                  phone=word_info["customers__phone"])

            new_record = Order(customers=customer, kumquats=kumquat, users_id=self.chatDBHandler.user_id,
                               quantity=word_info["quantity"], on_sold=word_info["on_sold"],
                               note=word_info.get("note", ""), book_date=datetime.datetime.now())
            new_record.get_amount()
            await new_record.save()
        logger.info(f"[process] Insert the data with query: {self.query}")
        return f"登记好啦，检查一下: \n{new_record.to_str(new_record)}\n{success_info}"

    async def del_one(self):
        #  TODO: 删除的好像用不到, 优先级不高， 放着吧
        pass
